home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / GAMES / C014.ZIP / LARN_SRC.ZIP / MAIN.C < prev    next >
C/C++ Source or Header  |  1993-11-17  |  41KB  |  1,320 lines

  1. /* main.c */
  2.  
  3. #ifdef MSDOS
  4. #include "errno.h"
  5. #include "setjmp.h"
  6. #include "stdlib.h"
  7. #endif
  8.  
  9. #include "header.h"
  10. #include "larndefs.h"
  11. #include "monsters.h"
  12. #include "objects.h"
  13. #include "player.h"
  14. #include "patchlev.h"
  15.  
  16. #ifndef MSDOS
  17. # ifndef VMS
  18. #  include <pwd.h>
  19. # endif VMS
  20. #endif MSDOS
  21.  
  22. extern char move_no_pickup;
  23. int dropflag=0; /* if 1 then don't lookforobject() next round */
  24. int rmst=80;    /*  random monster creation counter     */
  25. int userid;     /* the players login user id number */
  26. char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a
  27.                               move */
  28. static char viewflag=0;    /* if viewflag then we have done a 99 stay here
  29.                               and don't showcell in the main loop */
  30. char restorflag=0;         /* 1 means restore has been done    */
  31. char prompt_mode = 0;         /* 1 if prompting for actions */
  32.  
  33. #ifdef MSDOS
  34.  
  35. static char cmdhelp[] = "\
  36. Cmd line format: larn [-slicnhp] [-o<optsfile>] [-##] [++]\n\
  37.   -s   show the scoreboard\n\
  38.   -l   show the logfile (wizard id only)\n\
  39.   -i   show scoreboard with inventories of dead characters\n\
  40.   -c   create new scoreboard (wizard id only)\n\
  41.   -n   suppress welcome message on starting game\n\
  42.   -##  specify level of difficulty (example: -5)\n\
  43.   -h   print this help text\n\
  44.   -p   prompt for actions on objects\n\
  45.   ++   restore game from checkpoint file\n\
  46.   -o<optsfile>   specify larnopts filename to be used instead of \"larn.opt\"\n\
  47. ";
  48.  
  49. # else
  50.  
  51. static char cmdhelp[] = "\
  52. Cmd line format: larn [-slicnhp] [-o<optsfile>] [-##] [++]\n\
  53.   -s   show the scoreboard\n\
  54.   -l   show the logfile (wizard id only)\n\
  55.   -i   show scoreboard with inventories of dead characters\n\
  56.   -c   create new scoreboard (wizard id only)\n\
  57.   -n   suppress welcome message on starting game\n\
  58.   -##  specify level of difficulty (example: -5)\n\
  59.   -h   print this help text\n\
  60.   -p   prompt for actions on objects\n\
  61.   ++   restore game from checkpoint file\n\
  62.   -o<optsfile>   specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
  63. ";
  64.  
  65. # endif
  66.  
  67. #ifdef MSDOS
  68. int save_mode = 0;      /* 1 if doing a save game */
  69. jmp_buf save_jbuf;      /* To recover from disk full errors */
  70. #endif
  71.  
  72. #ifdef VT100
  73. static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
  74.     "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
  75.     "vt341"  };
  76. #endif
  77.  
  78. #ifdef VMS
  79. # define EXIT_FAILURE
  80. # define EXIT_SUCCESS 1
  81. #else
  82. # define EXIT_FAILURE 1
  83. # define EXIT_SUCCESS 0
  84. #endif
  85.  
  86. /*
  87.     ************
  88.     MAIN PROGRAM
  89.     ************
  90. */
  91. main(argc,argv)
  92.     int argc;
  93.     char **argv;
  94.     {
  95.     register int i,j;
  96.     int hard = -1;
  97.     char *ptr=0;
  98. #ifdef VT100
  99.     char *ttype;
  100. #endif
  101. #ifndef MSDOS
  102.     struct passwd *pwe,*getpwuid();
  103. #endif
  104.  
  105. /*
  106.  *  first task is to identify the player
  107.  */
  108. #ifndef VT100
  109.     init_term();    /* setup the terminal (find out what type) for termcap */
  110. #endif
  111. #ifdef MSDOS
  112.     ptr = "PLAYER";
  113. #else
  114. #ifdef VMS
  115.     ptr = getenv("USER");
  116. #else
  117.     if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */
  118.       if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
  119.         ptr = pwe->pw_name;
  120.       else
  121.       if ((ptr = getenv("USER")) == 0)
  122.         if ((ptr = getenv("LOGNAME")) == 0)
  123.           {
  124.           noone: write(2, "Can't find your logname.  Who Are You?\n",39);
  125.                  exit();
  126.           }
  127.     if (ptr==0) goto noone;
  128.     if (strlen(ptr)==0) goto noone;
  129. #endif
  130. #endif
  131.  
  132. /*
  133.  *  second task is to prepare the pathnames the player will need
  134.  */
  135.     strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
  136.     strcpy(logname,ptr);    /* this will be overwritten with the players name */
  137.  
  138. /* Set up the input and output buffers.
  139.  */
  140.     lpbuf    = (char *)malloc((5* BUFBIG)>>2);  /* output buffer */
  141.     inbuffer = (char *)malloc((5*MAXIBUF)>>2);  /* output buffer */
  142.     if ((lpbuf==0) || (inbuffer==0)) 
  143.         died(-285); /* malloc() failure */
  144.  
  145. # ifdef MSDOS
  146.     /* LARNHOME now comes from the options file, so it must be read in
  147.      * before constructing the other file names.  Unfortunately we have
  148.      * to look for the -o option now.
  149.      */
  150.     strcpy(optsfile, LARNOPTS);
  151.     for (i = 1; i < argc; i++)
  152.         if (strncmp(argv[i], "-o", 2) == 0) 
  153.             {
  154.             argv[i][0] = 0;         /* remove this argv */
  155.             if (argv[i][2] != '\0')
  156.                 strncpy(optsfile, &argv[i][2], PATHLEN);
  157.             else
  158.                 {
  159.                 strncpy(optsfile, argv[i + 1], PATHLEN);
  160.                 argv[i + 1][0] = 0; /* and this argv */
  161.                 }
  162.             optsfile[PATHLEN - 1] = 0;
  163.             break;
  164.             }
  165.     readopts();
  166.     append_slash(larndir);
  167.  
  168.     /* Savefile and swapfile can be given explicitly as options
  169.      */
  170.     if (!savefilename[0]) 
  171.         {
  172.         strcpy(savefilename, larndir);
  173.         strcat(savefilename, SAVEFILE);
  174.         }
  175.     if (!swapfile[0]) 
  176.         {
  177.         strcpy(swapfile, larndir);
  178.         strcat(swapfile, SWAPFILE);
  179.         }
  180.     strcpy(scorefile, larndir);
  181.     strcpy(logfile, larndir);
  182.     strcpy(helpfile, larndir);
  183.     strcpy(larnlevels, larndir);
  184.     strcpy(fortfile, larndir);
  185.     strcpy(playerids, larndir);
  186.     strcpy(ckpfile, larndir);
  187.  
  188. # else /* MSDOS */
  189.  
  190.     if ((ptr = getenv("HOME")) == 0) 
  191.         ptr = ".";
  192. #ifdef SAVEINHOME
  193.     /* save file name in home directory */
  194. # ifdef VMS
  195.     sprintf(savefilename, "%s%s",ptr, SAVEFILE);
  196. # else
  197.     sprintf(savefilename, "%s/%s",ptr, SAVEFILE);
  198. # endif VMS
  199. #else
  200.     strcat(savefilename,logname);   /* prepare savefile name */
  201.     strcat(savefilename,".sav");    /* prepare savefile name */
  202. #endif
  203. #ifdef VMS
  204.     sprintf(optsfile, "%s%s",ptr, LARNOPTS);   /* the options filename */
  205. #else
  206.     sprintf(optsfile, "%s/%s",ptr, LARNOPTS);   /* the options filename */
  207. #endif VMS
  208.  
  209. # endif /* MSDOS */
  210.  
  211.     strcat(scorefile, SCORENAME);   /* the larn scoreboard filename */
  212.     strcat(logfile, LOGFNAME);      /* larn activity logging filename */
  213.     strcat(helpfile, HELPNAME);     /* the larn on-line help file */
  214.     strcat(larnlevels, LEVELSNAME); /* the pre-made cave level data file */
  215.     strcat(fortfile, FORTSNAME);    /* the fortune data file name */
  216.     strcat(playerids, PLAYERIDS);   /* the playerid data file name */
  217.     strcat(ckpfile, CKPFILE);
  218.  
  219. # ifdef TIMECHECK
  220.     strcat(holifile, HOLIFILE);     /* the holiday data file name */
  221. # endif
  222.  
  223. #ifdef VT100
  224. /*
  225.  *  check terminal type to avoid users who have not vt100 type terminals
  226.  */
  227.     ttype = getenv("TERM");
  228.     for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
  229.         if (strcmp(ttype,termtypes[i]) == 0) { j=0;  break; }
  230.     if (j)
  231.         {
  232.         lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
  233.         exit(EXIT_FAILURE);
  234.         }
  235. #endif
  236.  
  237. /*
  238.  *  now make scoreboard if it is not there (don't clear) 
  239.  */
  240.     if (access(scorefile,0) == -1) /* not there */
  241.         makeboard();
  242.  
  243. /*
  244.  *  now process the command line arguments 
  245.  */
  246.     for (i=1; i<argc; i++)
  247.         {
  248.         if (argv[i][0] == '-')
  249.           switch(argv[i][1])
  250.             {
  251.             case 's':          /* show scoreboard   */
  252.                 showscores();
  253.                 exit(EXIT_SUCCESS);
  254.  
  255.             case 'l':          /* show log file     */
  256.                 diedlog();
  257.                 exit(EXIT_SUCCESS);
  258.  
  259.             case 'i':          /* show all scoreboard */
  260.                 showallscores();
  261.                 exit(EXIT_SUCCESS);
  262.  
  263.             case 'c':          /* anyone with password can create scoreboard */
  264.                 lprcat("Preparing to initialize the scoreboard.\n");
  265.                 if (getpassword() != 0)  /*make new scoreboard*/
  266.                     {
  267.                     makeboard();
  268.                     lprc('\n');
  269.                     showscores();
  270.                     }
  271.                 exit(EXIT_SUCCESS);
  272.  
  273.             case 'n':          /* no welcome msg   */
  274.                 nowelcome=1;
  275.                 argv[i][0]=0;
  276.                 break;
  277.  
  278.             case '0': case '1': case '2': case '3': case '4': case '5':
  279.             case '6': case '7': case '8': case '9': /* for hardness */
  280.                 hard = atoi(&argv[i][1]);
  281.                 break;
  282.  
  283.             case 'h':          /* print out command line arguments */
  284.             case '?':
  285.                 write(1,cmdhelp,sizeof(cmdhelp));
  286.                 exit(EXIT_SUCCESS);
  287.  
  288.             case 'o':          /* specify a .larnopts filename */
  289.                 if (argv[i]+2 != '\0')
  290.                     strncpy(optsfile,argv[i]+2,127);
  291.                 else
  292.                     {
  293.                     strncpy( optsfile, argv[i+1][0], 127 );
  294.                     argv[i+1][0] = '\0';
  295.                     }
  296.                 break;
  297.  
  298.             case 'p':          /* set 'prompt_mode' flag */
  299.                 prompt_mode = 1 ;
  300.                 break ;
  301.  
  302.             default:
  303.                 printf("Unknown option <%s>\n",argv[i]);
  304.                 write(1,cmdhelp,sizeof(cmdhelp));
  305.                 exit(EXIT_SUCCESS);
  306.             };
  307.  
  308.         if (strcmp(argv[i], "++") == 0)
  309.             restorflag = 1;
  310.     }
  311.  
  312. #ifndef MSDOS
  313.     readopts();     /* read the options file if there is one */
  314. #endif
  315.  
  316. #ifdef TIMECHECK
  317. /*
  318.  *  this section of code checks to see if larn is allowed during working hours
  319.  */
  320.     if (dayplay==0) /* check for not-during-daytime-hours */
  321.       if (playable())
  322.         {
  323.         write(2,"Sorry, Larn can not be played during working hours.\n",52);
  324.         exit(EXIT_SUCCESS);
  325.         }
  326. #endif TIMECHECK
  327.  
  328. #ifdef UIDSCORE
  329.     userid = geteuid(); /* obtain the user's effective id number */
  330. #else UIDSCORE
  331.     userid = getplid(logname);  /* obtain the players id number */
  332. #endif UIDSCORE
  333. #ifdef VMS
  334.     wisid = userid;
  335. #endif
  336.     if (userid < 0) 
  337.         { 
  338.         write(2,"Can't obtain playerid\n",22);
  339.         exit(EXIT_SUCCESS);
  340.         }
  341.  
  342. #ifdef HIDEBYLINK
  343. /*
  344.  *  this section of code causes the program to look like something else to ps
  345.  */
  346.     if (strcmp(psname,argv[0])) /* if a different process name only */
  347.         {
  348.         if ((i=access(psname,1)) < 0)
  349.             {       /* link not there */
  350.             if (link(argv[0],psname)>=0)
  351.                 {
  352.                 argv[0] = psname;   execv(psname,argv);
  353.                 }
  354.             }
  355.         else
  356.             unlink(psname);
  357.         }
  358.  
  359.     for (i=1; i<argc; i++)
  360.         {
  361.         szero(argv[i]); /* zero the argument to avoid ps snooping */
  362.         }
  363. #endif HIDEBYLINK
  364.  
  365. /*
  366.  *  He really wants to play, so malloc the memory for the dungeon.
  367.  */
  368. # ifdef MSDOS
  369.     allocate_memory();
  370. # else
  371.     cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
  372.     if (cell == 0) died(-285);  /* malloc failure */
  373. # endif
  374.     lcreat((char*)0);   
  375.     newgame();      /*  set the initial clock  */
  376.  
  377.     if (restorflag == 1)           /* restore checkpoint file */
  378.         {
  379.         clear();
  380.         hitflag = 1;
  381.         restoregame(ckpfile);
  382.         }
  383.     else if (access(savefilename,0)==0)   /* restore game if need to */
  384.         {
  385.         clear();    
  386.         restorflag = 1;
  387.         hitflag=1;  
  388.         restoregame(savefilename);  /* restore last game    */
  389.         }
  390.     sigsetup();     /* trap all needed signals  */
  391.     setupvt100();   /*  setup the terminal special mode             */
  392.     sethard(hard);  /* set up the desired difficulty                */
  393.     if (c[HP]==0)   /* create new game */
  394.         {
  395.         makeplayer();   /*  make the character that will play           */
  396.         newcavelevel(0);/*  make the dungeon                            */
  397.         predostuff = 1; /* tell signals that we are in the welcome screen */
  398.         if (nowelcome==0)
  399.             welcome();     /* welcome the player to the game */
  400. # ifdef MSDOS
  401.         /* Display their mail if they've just won the previous game
  402.          */
  403.         checkmail();
  404. # endif
  405.         }
  406.  
  407.     lprc(T_INIT);   /* Reinit the screen because of welcome and check mail
  408.                      * having embedded escape sequences.*/
  409.     drawscreen();   /*  show the initial dungeon                    */
  410.     predostuff = 2; /* tell the trap functions that they must do a showplayer()
  411.                from here on */
  412.     /* nice(1); /* games should be run niced */
  413.     yrepcount = hit2flag = 0;
  414.     /* init previous player position to be current position, so we don't
  415.        reveal any stuff on the screen prematurely.
  416.     */
  417.     oldx = playerx ;
  418.     oldy = playery;
  419.     gtime = -1;
  420.  
  421.     /* MAINLOOP
  422.        find objects, move stuff, get commands, regenerate
  423.     */
  424.     while (1)
  425.         {
  426.         if (dropflag==0)
  427.             /* see if there is an object here.
  428.  
  429.                If in prompt mode, identify and prompt; else
  430.                identify, pickup if ( auto pickup and not move-no-pickup ),
  431.                never prompt.
  432.             */
  433.             if (prompt_mode)
  434.                 lookforobject( TRUE, FALSE, TRUE );
  435.             else
  436.                 lookforobject( TRUE, ( auto_pickup && !move_no_pickup ), FALSE );
  437.             else
  438.                 dropflag=0; /* don't show it just dropped an item */
  439.  
  440.         /* handle global activity
  441.            update game time, move spheres, move walls, move monsters
  442.            all the stuff affected by TIMESTOP and HASTESELF
  443.         */
  444.         if (c[TIMESTOP] <= 0)
  445.             if (c[HASTESELF] == 0 ||
  446.                (c[HASTESELF] & 1) == 0)
  447.                 {
  448.                 gtime++;
  449.                 movsphere();
  450.  
  451.                 if (hitflag==0)
  452.                     {
  453.                     if (c[HASTEMONST])
  454.                         movemonst();
  455.                     movemonst();
  456.                     }
  457.                 }
  458.  
  459.         /* show stuff around the player
  460.         */
  461.         if (viewflag==0)
  462.             showcell(playerx,playery);
  463.         else
  464.             viewflag=0;
  465.  
  466.         if (hit3flag)
  467.             lflushall();
  468.         hitflag=hit3flag=0;
  469.         bot_linex();    /* update bottom line */
  470.  
  471.         /* get commands and make moves
  472.         */
  473.         nomove=1;
  474.         while (nomove)
  475.             {
  476.             if (hit3flag)
  477.                 lflushall();
  478.             nomove=0;
  479.             parse();
  480.             }
  481.         regen();            /*  regenerate hp and spells            */
  482.         if (c[TIMESTOP]==0)
  483.             if (--rmst <= 0)
  484.                 {
  485.                 rmst = 120-(level<<2);
  486.                 fillmonst(makemonst(level));
  487.                 }
  488.         }
  489.     }
  490.  
  491. /*
  492.     subroutine to randomly create monsters if needed
  493.  */
  494. static randmonst()
  495.     {
  496.     if (c[TIMESTOP]) return;    /*  don't make monsters if time is stopped  */
  497.     if (--rmst <= 0)
  498.         {
  499.         rmst = 120 - (level<<2);  fillmonst(makemonst(level));
  500.         }
  501.     }
  502.  
  503.  
  504. /*
  505.     parse()
  506.  
  507.     get and execute a command
  508.  */
  509. static parse()
  510.     {
  511.     register int i,j,k,flag;
  512.     extern showeat(),showquaff(),showread();
  513.  
  514.     while   (1)
  515.         {
  516.         k = yylex();
  517.         switch(k)   /*  get the token from the input and switch on it   */
  518.             {
  519.             case 'h':   moveplayer(4);  return;     /*  west        */
  520.             case 'H':   run(4);         return;     /*  west        */
  521.             case 'l':   moveplayer(2);  return;     /*  east        */
  522.             case 'L':   run(2);         return;     /*  east        */
  523.             case 'j':   moveplayer(1);  return;     /*  south       */
  524.             case 'J':   run(1);         return;     /*  south       */
  525.             case 'k':   moveplayer(3);  return;     /*  north       */
  526.             case 'K':   run(3);         return;     /*  north       */
  527.             case 'u':   moveplayer(5);  return;     /*  northeast   */
  528.             case 'U':   run(5);         return;     /*  northeast   */
  529.             case 'y':   moveplayer(6);  return;     /*  northwest   */
  530.             case 'Y':   run(6);         return;     /*  northwest   */
  531.             case 'n':   moveplayer(7);  return;     /*  southeast   */
  532.             case 'N':   run(7);         return;     /*  southeast   */
  533.             case 'b':   moveplayer(8);  return;     /*  southwest   */
  534.             case 'B':   run(8);         return;     /*  southwest   */
  535.  
  536.             case '.':                               /*  stay here       */
  537.                 if (yrepcount) 
  538.                     viewflag=1;
  539.                 return;
  540.  
  541.             case 'c':
  542.                 yrepcount=0;
  543.                 cast();
  544.                 return;     /*  cast a spell    */
  545.  
  546.             case 'd':
  547.                 yrepcount=0;
  548.                 if (c[TIMESTOP]==0)
  549.                     dropobj();
  550.                 return; /*  to drop an object   */
  551.  
  552.             case 'e':
  553.                 yrepcount=0;
  554.                 if (c[TIMESTOP]==0)
  555.                     if (!floor_consume( OCOOKIE, "eat" ))
  556.                         consume( OCOOKIE, "eat", showeat );
  557.                 return; /*  to eat a fortune cookie */
  558.  
  559.             case 'g':   
  560.                 yrepcount = 0 ;
  561.                 cursors();
  562.                 lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
  563.                 break ;
  564.  
  565.             case 'i':       /* inventory */
  566.                 yrepcount=0;
  567.                 nomove=1;
  568.                 showstr(FALSE);
  569.                 return;
  570.  
  571.             case 'p':           /* pray at an altar */
  572.                 yrepcount = 0;
  573.                 if (!prompt_mode)
  574.                     pray_at_altar();
  575.                 else
  576.                     nomove = 1;
  577.                 return;
  578.  
  579.             case 'q':           /* quaff a potion */
  580.                 yrepcount=0;
  581.                 if (c[TIMESTOP]==0)
  582.                     if (!floor_consume( OPOTION, "quaff"))
  583.                         consume( OPOTION, "quaff", showquaff );
  584.                 return;
  585.  
  586.             case 'r':
  587.                 yrepcount=0;
  588.                 if (c[BLINDCOUNT])
  589.                     {
  590.                     cursors();
  591.                     lprcat("\nYou can't read anything when you're blind!");
  592.                     }
  593.                 else if (c[TIMESTOP]==0)
  594.                     if (!floor_consume( OSCROLL, "read" ))
  595.                         if (!floor_consume( OBOOK, "read" ))
  596.                             consume( OSCROLL, "read", showread );
  597.                 return;     /*  to read a scroll    */
  598.  
  599.             case 's':
  600.                 yrepcount = 0 ;
  601.                 if (!prompt_mode)
  602.                     sit_on_throne();
  603.                 else
  604.                     nomove = 1;
  605.                 return ;
  606.  
  607.             case 't':                       /* Tidy up at fountain */
  608.                 yrepcount = 0 ;
  609.                 if (!prompt_mode)
  610.                     wash_fountain() ;
  611.                 else
  612.                     nomove = 1;
  613.                 return ;
  614.  
  615.             case 'v':
  616.                 yrepcount=0;
  617.                 nomove = 1;
  618.                 cursors();
  619.                 lprintf("\nCaverns of Larn, Version %d.%d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)PATCHLEVEL,(long)c[HARDGAME]);
  620.                 if (wizard)
  621.                     lprcat(" Wizard");
  622.                 if (cheat) 
  623.                     lprcat(" Cheater");
  624.                 lprcat("\nThis version of Larn by Kevin Routley");
  625.                 return;
  626.  
  627.             case 'w':                       /*  wield a weapon */
  628.                 yrepcount=0;
  629.                 wield();
  630.                 return;
  631.  
  632.             case 'A':
  633.                 yrepcount = 0;
  634.                 if (!prompt_mode)
  635.                     desecrate_altar();
  636.                 else
  637.                     nomove = 1;
  638.                 return;
  639.  
  640.             case 'C':                       /* Close something */
  641.                 yrepcount = 0 ;
  642.                 if (!prompt_mode)
  643.                     close_something();
  644.                 else
  645.                     nomove = 1;
  646.                 return;
  647.  
  648.             case 'D':                       /* Drink at fountain */
  649.                 yrepcount = 0 ;
  650.                 if (!prompt_mode)
  651.                     drink_fountain() ;
  652.                 else
  653.                     nomove = 1;
  654.                 return ;
  655.  
  656.             case 'E':               /* Enter a building */
  657.                 yrepcount = 0 ;
  658.                 if (!prompt_mode)
  659.                     enter() ;
  660.                 else
  661.                     nomove = 1;
  662.                 break ;
  663.  
  664.             case 'I':              /*  list spells and scrolls */
  665.                 yrepcount=0;
  666.                 seemagic(0);
  667.                 nomove=1;
  668.                 return;
  669.  
  670.             case 'O':               /* Open something */
  671.                 yrepcount = 0 ;
  672.                 if (!prompt_mode)
  673.                     open_something();
  674.                 else
  675.                     nomove = 1;
  676.                 return;
  677.  
  678.             case 'P':
  679.                 cursors();
  680.                 yrepcount = 0;
  681.                 nomove = 1;
  682.                 if (outstanding_taxes>0)
  683.                     lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
  684.                 else
  685.                     lprcat("\nYou do not owe any taxes.");
  686.                 return;
  687.  
  688.             case 'Q':    /*  quit        */
  689.                 yrepcount=0;
  690.                 quit();
  691.                 nomove=1;
  692.                 return;
  693.  
  694.             case 'R' :          /* remove gems from a throne */
  695.                 yrepcount = 0 ;
  696.                 if (!prompt_mode)
  697.                     remove_gems( );
  698.                 else
  699.                     nomove = 1;
  700.                 return ;
  701.  
  702. # ifdef MSDOS
  703.             case 'S':
  704.                 /* Set up error recovery
  705.                  */
  706.                 if (setjmp(save_jbuf) != 0) {
  707.  
  708.                     /* can't use lwclose!
  709.                      */
  710.                     if (lfd > 2)
  711.                         close(lfd);
  712.                     lcreat(NULL);
  713.                     setscroll();
  714.                     cursors();
  715.                     lprcat("\nSave failed !\n");
  716.                     if (errno == ENOSPC)
  717.                         lprcat("Disk is full !\n");
  718.                     beep();
  719.                     (void) unlink(savefilename);
  720.                     save_mode = 0;
  721.                     yrepcount = 0;
  722.                     nomove = 1;
  723.                     break;
  724.                 }
  725.  
  726.                 /* And do the save.
  727.                  */
  728.                 cursors();
  729.                 lprintf("\nSaving to `%s' . . . ", savefilename);
  730.                 lflush();
  731.                 save_mode = 1;
  732.                 savegame(savefilename);
  733.                 clear();
  734.                 lflush();
  735.                 wizard=1;
  736.                 died(-257); /* doesn't return */
  737.                 break;
  738. # else
  739.             case 'S':   clear();  lprcat("Saving . . ."); lflush();  
  740.                         savegame(savefilename); wizard=1; died(-257);   /*  save the game - doesn't return  */
  741. # endif MSDOS
  742.  
  743.             case 'T':   yrepcount=0;    cursors();  if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
  744.                                         if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
  745.                         else lprcat("\nYou aren't wearing anything");
  746.                         return;
  747.  
  748.             case 'W':
  749.                 yrepcount=0;
  750.                 wear();
  751.                 return; /*  wear armor  */
  752.  
  753.             case 'Z':
  754.                 yrepcount=0;
  755.                 if (c[LEVEL]>9) 
  756.                     { 
  757.                     oteleport(1);
  758.                     return; 
  759.                     }
  760.                 cursors(); 
  761.                 lprcat("\nAs yet, you don't have enough experience to use teleportation");
  762.                 return; /*  teleport yourself   */
  763.  
  764.             case ' ':   yrepcount=0;    nomove=1;  return;
  765.  
  766. # ifdef MSDOS
  767.             case 'D'-64:
  768.                 yrepcount = 0;
  769.                 nomove = 1;
  770.                 levelinfo();
  771.                 return;
  772. # endif
  773.  
  774.             case 'L'-64:  yrepcount=0;  drawscreen();  nomove=1; return;    /*  look        */
  775.  
  776. #if WIZID
  777. #ifdef EXTRA
  778.             case 'A'-64:    yrepcount=0;    nomove=1; if (wizard) { diag(); return; }  /*   create diagnostic file */
  779.                         return;
  780. #endif
  781. #endif
  782.             case '<':                       /* Go up stairs or vol shaft */
  783.                 yrepcount = 0 ;
  784.                 if (!prompt_mode)
  785.                     up_stairs();
  786.         else
  787.             nomove = 1;
  788.                 return ;
  789.  
  790.             case '>':                       /* Go down stairs or vol shaft*/
  791.                 yrepcount = 0 ;
  792.                 if (!prompt_mode)
  793.                     down_stairs();
  794.         else
  795.             nomove = 1;
  796.                 return ;
  797.  
  798.             case '?':                       /* give the help screen */
  799.                 yrepcount=0;
  800.                 help();
  801.                 nomove=1;
  802.                 return; 
  803.  
  804.         case ',':                       /* pick up an item */
  805.             yrepcount = 0 ;
  806.             if (!prompt_mode)
  807.             /* pickup, don't identify or prompt for action */
  808.             lookforobject( FALSE, TRUE, FALSE );
  809.         else
  810.             nomove = 1;
  811.         return;
  812.  
  813.             case ':':                       /* look at object */
  814.                 yrepcount = 0 ;
  815.                 if (!prompt_mode)
  816.             /* identify, don't pick up or prompt for action */
  817.                     lookforobject( TRUE, FALSE, FALSE );
  818.                 nomove = 1;  /* assumes look takes no time */
  819.                 return;
  820.  
  821.         case '@':       /* toggle auto-pickup */
  822.             yrepcount = 0 ;
  823.             nomove = 1;
  824.             cursors();
  825.             lprcat("\nAuto pickup: ");
  826.             auto_pickup = !auto_pickup;
  827.             if (auto_pickup)
  828.                 lprcat("On.");
  829.             else
  830.                 lprcat("Off.");
  831.             return;
  832.  
  833.         case '/':        /* identify object/monster */
  834.             specify_object();
  835.             nomove = 1 ;
  836.             yrepcount = 0 ;
  837.             return;
  838.  
  839.         case '^':                       /* identify traps */
  840.                 flag = yrepcount = 0;
  841.                 cursors();
  842.                 lprc('\n');
  843.                 for (j=playery-1; j<playery+2; j++)
  844.                     {
  845.                     if (j < 0)
  846.                         j=0;
  847.                     if (j >= MAXY)
  848.                         break;
  849.                     for (i=playerx-1; i<playerx+2; i++)
  850.                         {
  851.                         if (i < 0) 
  852.                             i=0;
  853.                         if (i >= MAXX) 
  854.                             break;
  855.                         switch(item[i][j])
  856.                             {
  857.                             case OTRAPDOOR:     case ODARTRAP:
  858.                             case OTRAPARROW:    case OTELEPORTER:
  859.                             case OPIT:
  860.                                 lprcat("\nIts ");
  861.                                 lprcat(objectname[item[i][j]]);
  862.                                 flag++;
  863.                             };
  864.                         }
  865.                     }
  866.                 if (flag==0) 
  867.                     lprcat("\nNo traps are visible");
  868.                 return;
  869.  
  870. #if WIZID
  871.             case '_':   /*  this is the fudge player password for wizard mode*/
  872.                         yrepcount=0;    cursors(); nomove=1;
  873. # ifndef MSDOS
  874.                         if (userid!=wisid)
  875.                             {
  876.                             lprcat("Sorry, you are not empowered to be a wizard.\n");
  877.                             scbr(); /* system("stty -echo cbreak"); */
  878.                             lflush();  return;
  879.                             }
  880. # endif
  881.                         if (getpassword()==0)
  882.                             {
  883.                             scbr(); /* system("stty -echo cbreak"); */ return;
  884.                             }
  885.                         wizard=1;  scbr(); /* system("stty -echo cbreak"); */
  886.                         for (i=0; i<6; i++)  c[i]=70;  iven[0]=iven[1]=0;
  887.                         take(OPROTRING,50);   take(OLANCE,25);  c[WIELD]=1;
  888.                         c[LANCEDEATH]=1;   c[WEAR] = c[SHIELD] = -1;
  889.                         raiseexperience(6000000L);  c[AWARENESS] += 25000;
  890.                         {
  891.                         register int i,j;
  892.                         for (i=0; i<MAXY; i++)
  893.                             for (j=0; j<MAXX; j++)  know[j][i]=KNOWALL;
  894.                         for (i=0; i<SPNUM; i++) spelknow[i]=1;
  895.                         for (i=0; i<MAXSCROLL; i++)  scrollname[i][0]=' ';
  896.                         for (i=0; i<MAXPOTION; i++)  potionname[i][0]=' ';
  897.                         }
  898.                         for (i=0; i<MAXSCROLL; i++)
  899.                           if (strlen(scrollname[i])>2) /* no null items */
  900.                             { item[i][0]=OSCROLL; iarg[i][0]=i; }
  901.                         for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
  902.                           if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
  903.                             { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
  904.                         for (i=1; i<MAXY; i++)
  905.                             { item[0][i]=i; iarg[0][i]=0; }
  906.                         for (i=MAXY; i<MAXY+MAXX; i++)
  907.                             { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
  908.             for (i=MAXX+MAXY; i<MAXOBJECT; i++)
  909.                 {
  910.                 item[MAXX-1][i-MAXX-MAXY]=i;
  911.                 iarg[MAXX-1][i-MAXX-MAXY]=0;
  912.                 }
  913.                         c[GOLD]+=250000;    drawscreen();   return;
  914. #endif
  915.  
  916.             };
  917.         }
  918.     }
  919.  
  920. parse2()
  921.     {
  922.     if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters       */
  923.     randmonst();    regen();
  924.     }
  925.  
  926. static run(dir)
  927.     int dir;
  928.     {
  929.     register int i;
  930.     i=1; while (i)
  931.         {
  932.         i=moveplayer(dir);
  933.         if (i>0) {  if (c[HASTEMONST]) movemonst();  movemonst(); randmonst(); regen(); }
  934.         if (hitflag) i=0;
  935.         if (i!=0)  showcell(playerx,playery);
  936.         }
  937.     }
  938.  
  939. /*
  940.     function to wield a weapon
  941.  */
  942. static wield()
  943.     {
  944.     register int i;
  945.     while (1)
  946.         {
  947.         if ((i = whatitem("wield (- for nothing)")) == '\33')
  948.         return;
  949.         if (i != '.')
  950.             {
  951.             if (i=='*')
  952.                 {
  953.                 i = showwield();
  954.                 cursors();
  955.                 }
  956.             if ( i == '-' )
  957.                 {
  958.                 c[WIELD] = -1 ;
  959.                 bottomline();
  960.                 return;
  961.                 }
  962.             if (i && i != '.')
  963.                 if (iven[i-'a']==0)
  964.                     { ydhi(i); return; }
  965.                 else if (iven[i-'a']==OPOTION)
  966.                     { ycwi(i); return; }
  967.             else if (iven[i-'a']==OSCROLL)
  968.                     { ycwi(i); return; }
  969.             else if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD))
  970.                     { lprcat("\nBut one arm is busy with your shield!");
  971.                       return; }
  972.             else
  973.                 {
  974.                 c[WIELD]=i-'a';
  975.                 if (iven[i-'a'] == OLANCE)
  976.                     c[LANCEDEATH]=1;
  977.                 else c[LANCEDEATH]=0;
  978.                 bottomline();
  979.                 return;
  980.                 }
  981.             }
  982.         }
  983.     }
  984.  
  985. /*
  986.     common routine to say you don't have an item
  987.  */
  988. static ydhi(x)
  989.     int x;
  990.     { cursors();  lprintf("\nYou don't have item %c!",x); }
  991. static ycwi(x)
  992.     int x;
  993.     { cursors();  lprintf("\nYou can't wield item %c!",x); }
  994.  
  995. /*
  996.     function to wear armor
  997.  */
  998. static wear()
  999.     {
  1000.     register int i;
  1001.     while (1)
  1002.         {
  1003.         if ((i = whatitem("wear"))=='\33')
  1004.             return;
  1005.         if (i != '.' && i != '-')
  1006.             {
  1007.             if (i=='*')
  1008.                 {
  1009.                 i = showwear();
  1010.                 cursors();
  1011.                 }
  1012.             if (i && i != '.')
  1013.                 switch(iven[i-'a'])
  1014.                     {
  1015.                     case 0:
  1016.                         ydhi(i);
  1017.                         return;
  1018.                     case OLEATHER:  case OCHAIN:  case OPLATE:
  1019.                     case ORING:     case OSPLINT: case OPLATEARMOR:
  1020.                     case OSTUDLEATHER:            case OSSPLATE:
  1021.                         if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
  1022.                             c[WEAR]=i-'a';  bottomline(); return;
  1023.                     case OSHIELD:   if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
  1024.                                 if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
  1025.                                 c[SHIELD] = i-'a';  bottomline(); return;
  1026.                     default:    lprcat("\nYou can't wear that!");
  1027.                     };
  1028.             }
  1029.         }
  1030.     }
  1031.  
  1032. /*
  1033.     function to drop an object
  1034.  */
  1035. static dropobj()
  1036.     {
  1037.     register int i;
  1038.     register char *p;
  1039.     long amt;
  1040.  
  1041.     p = &item[playerx][playery];
  1042.     while (1)
  1043.         {
  1044.         if ((i = whatitem("drop"))=='\33')  
  1045.         return;
  1046.     if (i=='*') 
  1047.         {
  1048.         i = showstr(TRUE);
  1049.         cursors();
  1050.         }
  1051.     if ( i != '-' )
  1052.             {
  1053.             if (i=='.') /* drop some gold */
  1054.                 {
  1055.                 if (*p) { lprcat("\nThere's something here already!"); return; }
  1056.                 lprcat("\n\n");
  1057.                 cl_dn(1,23);
  1058.                 lprcat("How much gold do you drop? ");
  1059.                 if ((amt=readnum((long)c[GOLD])) == 0) return;
  1060.                 if (amt>c[GOLD])
  1061.                     {
  1062. #ifndef MSDOS
  1063.             lprcat("\n");
  1064. #endif MSDOS
  1065.             lprcat("You don't have that much!");
  1066.             return; }
  1067.                 if (amt<=32767)
  1068.                     { *p=OGOLDPILE; i=amt; }
  1069.                 else if (amt<=327670L)
  1070.                     { *p=ODGOLD; i=amt/10; amt = 10L*i; }
  1071.                 else if (amt<=3276700L)
  1072.                     { *p=OMAXGOLD; i=amt/100; amt = 100L*i; }
  1073.                 else if (amt<=32767000L)
  1074.                     { *p=OKGOLD; i=amt/1000; amt = 1000L*i; }
  1075.                 else
  1076.                     { *p=OKGOLD; i=32767; amt = 32767000L; }
  1077.                 c[GOLD] -= amt;
  1078. #ifndef MSDOS
  1079.                 lprintf("You drop %d gold pieces",(long)amt);
  1080. #else
  1081.                 lprintf("\nYou drop %d gold pieces",(long)amt);
  1082. #endif MSDOS
  1083.                 iarg[playerx][playery]=i; bottomgold();
  1084.                 know[playerx][playery]=0; dropflag=1;  return;
  1085.                 }
  1086.         if (i)
  1087.         {
  1088.         drop_object(i-'a');
  1089.         return;
  1090.         }
  1091.             }
  1092.         }
  1093.     }
  1094.  
  1095. static int floor_consume( search_item, cons_verb )
  1096. int search_item;
  1097. char *cons_verb;
  1098.     {
  1099.     register int i;
  1100.     char tempc;
  1101.  
  1102.     cursors();
  1103.     i = item[playerx][playery];
  1104.  
  1105.     /* item not there, quit
  1106.     */
  1107.     if (i != search_item)
  1108.         return( 0 );
  1109.  
  1110.     /* item there.  does the player want to consume it?
  1111.     */
  1112.     lprintf("\nThere is %s", objectname[i] );
  1113.     if (i==OSCROLL)
  1114.         if (scrollname[iarg[playerx][playery]][0])
  1115.             lprintf(" of%s", scrollname[iarg[playerx][playery]]);
  1116.     if (i==OPOTION)
  1117.         if (potionname[iarg[playerx][playery]][0])
  1118.             lprintf(" of%s", potionname[iarg[playerx][playery]]);
  1119.     lprintf(" here.  Do you want to %s it?", cons_verb );
  1120.  
  1121.     if ((tempc = getyn()) == 'n' )
  1122.         return( 0 );                /* item there, not consumed */
  1123.     else if (tempc != 'y')
  1124.         {
  1125.         lprcat(" aborted");
  1126.         return( -1 );               /* abort */
  1127.         }
  1128.  
  1129.     /* consume the item.
  1130.     */
  1131.     switch( i )
  1132.         {
  1133.         case OCOOKIE:
  1134.             outfortune();
  1135.             forget();
  1136.             break;
  1137.         case OBOOK:
  1138.             readbook( iarg[playerx][playery] );
  1139.             forget();
  1140.             break;
  1141.         case OPOTION:
  1142.             quaffpotion( iarg[playerx][playery] );
  1143.             forget();
  1144.             break;
  1145.         case OSCROLL:
  1146.             /* scrolls are tricky because of teleport.
  1147.             */
  1148.             i = iarg[playerx][playery];
  1149.             know[playerx][playery] = 0;
  1150.             item[playerx][playery] = iarg[playerx][playery] = 0 ;
  1151.             read_scroll( i );
  1152.             break;
  1153.         }
  1154.     return( 1 );
  1155.     }
  1156.  
  1157. static int consume( search_item, prompt, showfunc )
  1158. int search_item ;
  1159. char *prompt;
  1160. int (*showfunc)();
  1161.     {
  1162.     register int i;
  1163.  
  1164.     while (1)
  1165.         {
  1166.         if ((i = whatitem( prompt )) == '\33')
  1167.             return;
  1168.         if (i != '.' && i != '-')
  1169.             {
  1170.             if (i == '*')
  1171.                 {
  1172.                 i = showfunc();
  1173.                 cursors();
  1174.                 }
  1175.             if (i && i != '.')
  1176.                 {
  1177.                 switch (iven[i-'a'])
  1178.                     {
  1179.                     case OSCROLL:
  1180.                         if ( search_item != OSCROLL )
  1181.                             {
  1182.                             lprintf("\nYou can't %s that.", prompt );
  1183.                             return;
  1184.                             }
  1185.                         read_scroll( ivenarg[i-'a'] );
  1186.                         break;
  1187.                     case OBOOK:
  1188.                         if ( search_item != OSCROLL )
  1189.                             {
  1190.                             lprintf("\nYou can't %s that.", prompt );
  1191.                             return;
  1192.                             }
  1193.                         readbook( ivenarg[i-'a'] );
  1194.                         break;
  1195.                     case OCOOKIE:
  1196.                         if ( search_item != OCOOKIE )
  1197.                             {
  1198.                             lprintf("\nYou can't %s that.", prompt );
  1199.                             return;
  1200.                             }
  1201.                         outfortune();
  1202.                         break;
  1203.                     case OPOTION:
  1204.                         if ( search_item != OPOTION )
  1205.                             {
  1206.                             lprintf("\nYou can't %s that.", prompt );
  1207.                             return;
  1208.                             }
  1209.                         quaffpotion( ivenarg[i-'a'], TRUE );
  1210.                         break;
  1211.                     case 0:
  1212.                         ydhi(i);
  1213.                         return;
  1214.                     default:
  1215.                         lprintf("\nYou can't %s that.", prompt );
  1216.                         return;
  1217.                     }
  1218.                 iven[i-'a'] = 0;
  1219.                 return;
  1220.                 }
  1221.             }
  1222.         }
  1223.     }
  1224.  
  1225. /*
  1226.     function to ask what player wants to do
  1227.  */
  1228. static whatitem(str)
  1229.     char *str;
  1230.     {
  1231.     int i=0;
  1232.     cursors();  lprintf("\nWhat do you want to %s [* for all] ? ",str);
  1233.     while (i>'z' || (i<'a' && i!='-' && i!='*' && i!='\33' && i!='.'))
  1234.         i=ttgetch();
  1235.     if (i=='\33')
  1236.         lprcat(" aborted");
  1237.     return(i);
  1238.     }
  1239.  
  1240. /*
  1241.     subroutine to get a number from the player
  1242.     and allow * to mean return amt, else return the number entered
  1243.  */
  1244. unsigned long readnum(mx)
  1245.     long mx;
  1246.     {
  1247.     register int i;
  1248.     register unsigned long amt=0;
  1249.  
  1250.     sncbr();
  1251.     /* allow him to say * for all gold 
  1252.     */
  1253.     if ((i=ttgetch()) == '*')
  1254.         amt = mx;
  1255.     else
  1256.         /* read chars into buffer, deleting when requested */
  1257.     while (i != '\n')
  1258.         {
  1259.         if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
  1260.         if ((i <= '9') && (i >= '0') && (amt<999999999))
  1261.             amt = amt*10+i-'0';
  1262.         if ((i=='\010') || (i=='\177'))
  1263.             amt = (long)(amt / 10) ;
  1264.         i = ttgetch();
  1265.         }
  1266.     scbr();
  1267.     return(amt);
  1268.     }
  1269.  
  1270. #ifdef HIDEBYLINK
  1271. /*
  1272.  *  routine to zero every byte in a string
  1273.  */
  1274. szero(str)
  1275.     register char *str;
  1276.     {
  1277.     while (*str)
  1278.         *str++ = 0;
  1279.     }
  1280. #endif HIDEBYLINK
  1281.  
  1282. #ifdef TIMECHECK
  1283. /*
  1284.  *  routine to check the time of day and return 1 if its during work hours
  1285.  *  checks the file ".holidays" for forms like "mmm dd comment..."
  1286.  */
  1287. int playable()
  1288.     {
  1289.     long g_time,time();
  1290.     int hour,day,year;
  1291.     char *date,*month,*p;
  1292.  
  1293.     time(&g_time);  /* get the time and date */
  1294.     date = ctime(&g_time); /* format: Fri Jul  4 00:27:56 EDT 1986 */
  1295.     year = atoi(date+20);
  1296.     hour = (date[11]-'0')*10 + date[12]-'0';
  1297.     day  = (date[8]!=' ') ? ((date[8]-'0')*10 + date[9]-'0') : (date[9]-'0');
  1298.     month = date+4;  date[7]=0; /* point to and NULL terminate month */
  1299.  
  1300.     if (((hour>=8 && hour<17)) /* 8AM - 5PM */
  1301.         && strncmp("Sat",date,3)!=0     /* not a Saturday */
  1302.         && strncmp("Sun",date,3)!=0)    /* not a Sunday */
  1303.             {
  1304.         /* now check for a .holidays datafile */
  1305.             lflush();
  1306.             if (lopen(holifile) >= 0)
  1307.                 for ( ; ; )
  1308.                     {
  1309.                     if ((p=lgetw())==0) break;
  1310.                     if (strlen(p)<6) continue;
  1311.                     if ((strncmp(p,month,3)==0) && (day==atoi(p+4)) && (year==atoi(p+7)))
  1312.                         return(0); /* a holiday */
  1313.                     }
  1314.             lrclose();  lcreat((char*)0);
  1315.             return(1);
  1316.             }
  1317.     return(0);
  1318.     }
  1319. #endif TIMECHECK
  1320.